package cz.muni.fi.pa165.hauntedhouses.facade;

import cz.muni.fi.pa165.hauntedhouses.dto.AbilityDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.AbilityType;
import cz.muni.fi.pa165.hauntedhouses.dto.AccountDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.GhostDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.HouseDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.HumanDTO;
import cz.muni.fi.pa165.hauntedhouses.service.AbilityService;
import cz.muni.fi.pa165.hauntedhouses.service.GhostService;
import cz.muni.fi.pa165.hauntedhouses.service.HouseService;
import cz.muni.fi.pa165.hauntedhouses.service.HumanService;
import cz.muni.fi.pa165.hauntedhouses.service.SecurityService;
import java.util.List;

/**
 *
 * @author Petr Suchý
 */
public interface ServiceFacade {


    /**
     * Inserts a single Human into a House. This method works with DTO objects already.
     *
     * @param house A house which we want to add human to.
     * @param human A human which is to be added into a House
     */
    void addHumanToHouse(HouseDTO house, HumanDTO human);

    void createAbility(AbilityDTO ability);

    void createGhost(GhostDTO ghost);

    void createHouse(HouseDTO house);

    void createHuman(HumanDTO human);

    List<AbilityDTO> findAbilitiesByName(String name);

    List<AbilityDTO> findAbilitiesByType(AbilityType at);

    List<AbilityDTO> findAllAbilities();

    List<GhostDTO> findAllGhosts();

    List<HouseDTO> findAllHouses();

    List<HumanDTO> findAllHumans();

    List<GhostDTO> findGhostsByHouse(HouseDTO house);

    List<GhostDTO> findGhostsByLevel(Integer level);

    List<GhostDTO> findGhostsByName(String name);

    List<GhostDTO> findGhostsByType(AbilityType type);

    List<HouseDTO> findHousesByName(String name);

    List<HumanDTO> findHumansByHouse(HouseDTO house);

    List<HumanDTO> findHumansByName(String name);

    AbilityDTO getAbility(Long id);

    GhostDTO getGhost(Long id);

    GhostService getGhostService();

    HouseDTO getHouse(Long id);

    HumanDTO getHuman(Long id);

    /**
     * Will be called when ghost reached some significant level. User will choose the ability to add
     *
     * @param ghost Player's ghost.
     * @param ability Ability to be added.
     */
    void grantNewAbility(GhostDTO ghost, AbilityDTO ability);

    void removeAbility(AbilityDTO ability);

    /**
     * Removes ability from ghost.
     *
     * @param ghost Player's ghost.
     * @param ability Ability to be removed.
     */
    void removeAbilityFromGhost(GhostDTO ghost, AbilityDTO ability);

    void removeGhost(GhostDTO ghost);

    void removeHouse(HouseDTO house);

    void removeHuman(HumanDTO human);

    /**
     * Removes a single person from a house. Works with DTO.
     *
     * @param house A target house where we want to removeGhost the human
     * @param human A human to be EXTERMINATED
     */
    void removeHumanFromHouse(HouseDTO house, HumanDTO human);

    void setAbilityService(AbilityService abilityService);

    void setGhostService(GhostService ghostService);
    
    void setSecurityService(SecurityService securityService);

    void setHouseService(HouseService houseService);

    void setHumanService(HumanService humanService);

    void updateAbility(AbilityDTO ability);

    void updateGhost(GhostDTO ghost);

    void updateHouse(HouseDTO house);

    void updateHuman(HumanDTO human);

    /**
     * Given the used ability, ghost owning this ability and targeted human this method scared the human, lowering his psyche and possibly scaring him
     * to death
     *
     * @param ability Used ability.
     * @param human Human to be scared.
     * @param ghost Ghost which uses the ability.
     */
    void useAbility(AbilityDTO ability, HumanDTO human, GhostDTO ghost);
    
    AccountDTO loginUser(String username, String password);
     
    AccountDTO registerUser(AccountDTO acc);
    
}
